/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package validator.tubes.ai.i;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;

/**
 *
 * @author Mahdan Ahmad F A
 */
public class NantoTheLover {
    private final int money;
    private final int weeks;
    private final int energy;
    private final int jmhKandidat;
    private final int jmhBarang;
    private final int strenght;
    private final int charm;
    private final int brain;
    private final ArrayList<Kandidat> listKandidat;
    private final ArrayList<Barang>   listBarang;
    private final ArrayList<Bangunan> listBangunan;
    
    public NantoTheLover() {
        money           = 0;
        weeks           = 0;
        energy          = 0;
        strenght        = 0;
        charm           = 0;
        brain           = 0;
        jmhKandidat     = 0;
        jmhBarang       = 0;
        listKandidat    = new ArrayList<>();
        listBarang      = new ArrayList<>();
        listBangunan    = new ArrayList<>();
    }
    
    public NantoTheLover(String a, String b, String c) throws FileNotFoundException {
        listKandidat    = new ArrayList<>();
        listBarang      = new ArrayList<>();
        listBangunan    = new ArrayList<>();
        
        FileReader general  = new FileReader(a);
        Scanner scanGeneral = new Scanner(general);
        
        FileReader jadwal_kandidat  = new FileReader(b);
        Scanner scanJadwalKandidat  = new Scanner(jadwal_kandidat);
        
        FileReader jadwal_tempat    = new FileReader(c);
        Scanner scanJadwalTempat    = new Scanner(jadwal_tempat);
        
        money       = scanGeneral.nextInt();
        weeks       = scanGeneral.nextInt();
        energy      = scanGeneral.nextInt();
        strenght    = scanGeneral.nextInt();
        charm       = scanGeneral.nextInt();
        brain       = scanGeneral.nextInt();
        
        jmhKandidat = scanGeneral.nextInt();
        
        for(int m = 0; m < jmhKandidat; m++) {
            listKandidat.add(new Kandidat(scanGeneral.nextInt(), scanGeneral.nextInt(), scanGeneral.nextInt(), scanGeneral.next(), scanGeneral.nextInt(), scanGeneral.nextInt(), scanGeneral.nextInt()));
            listKandidat.get(m).setjadwal(scanJadwalKandidat.nextLine());
        }
        
        jmhBarang   = scanGeneral.nextInt();
        
        for (int n = 0; n < jmhBarang; n++) {
            listBarang.add(new Barang(scanGeneral.next(), scanGeneral.nextInt(), scanGeneral.nextInt()));
        }
        
        listBangunan.add(new Mall(scanJadwalTempat.nextLine()));
        listBangunan.add(new Gymnasium(scanJadwalTempat.nextLine()));
        listBangunan.add(new Cafe(scanJadwalTempat.nextLine()));
        listBangunan.add(new University(scanJadwalTempat.nextLine()));
    }
    

    public int hitungenlight(String line) {
        int sum = 0;
        
        //int[] frekuensi = new int[jmhKandidat];
        
        for (int i = 0; i < line.length(); i++) {
            if (isKandidat(line.charAt(i))) {
                sum += listKandidat.get(line.charAt(i) - 49).getenlightenment();
                
                //frekuensi[line.charAt(i) - 49]++;
            }
        }
        
        /*
        for (int i = 0; i < frekuensi.length; i++) {
            System.out.println("Frekuensi kandidat ke-" + (i+1) + " = " + frekuensi[i]);
        }   // */
        
        return sum;
    }
    
    public String validate(String Line) {
        String message = "Penjadwalan valid";
        int jumlahHari = weeks*7;
        
        ArrayList<String> arrayHari = new ArrayList<>();
        for (int i = 0; i < (jumlahHari); i++) {
            arrayHari.add(Line.substring((i*12), ((i+1)*12)));
        }
        
        int count_day   = 0;
        int count_hour  = 0;
        
        int item_code   = 0;
        
        ArrayList<Integer> max_kenalan   = new ArrayList<>();
        ArrayList<Integer> stock_barang  = new ArrayList<>();
        
        ArrayList<Integer> jumlah_barang = new ArrayList<>();
        for (int i = 0; i < jmhBarang; i++) {
            jumlah_barang.add(0);
        }
        
        char some;
        int  pos = 0;
        
        boolean flag;
      
        int val_money    = money;
        int val_strenght = strenght;
        int val_charm    = charm;
        int val_brain    = brain;
        
        int pre_strenght = 0;
        int pre_charm    = 0;
        int pre_brain    = 0;
        
        int energyperday = energy;
        
        if (isInAll(Line)) {
            flag = true;
        } else {
            message = ("Tidak semua kandidat dikunjungi");
            flag = false;
        }
        
        while ((flag) && (count_day < jumlahHari)) {
            
            max_kenalan.clear();
            for (int i = 0; i < jmhKandidat; i++) {
                max_kenalan.add(listKandidat.get(i).getmax());
            }

            stock_barang.clear();
            for (int i = 0; i < jmhBarang; i++) {
                stock_barang.add(listBarang.get(i).getrestock());
            }
            
            count_hour   = 0;
            energyperday = energy;
            
            while ((flag) && (count_hour < 12)) {
                // Cek Jadwal
                
                some = arrayHari.get(count_day).charAt(count_hour);
                pos  = (count_day * 12) + count_hour;
                
                if (isBarang(some)) {
                    item_code = searchBarang(some);
                    
                    if (stock_barang.get(item_code) == 0) {
                        flag = false;
                        message = ("Stock barang sudah habis");
                        break;
                    } else {
                        val_money -= listBarang.get(item_code).getharga();
                        if (val_money < 0) {
                            flag = false;
                            message = ("Uang Nanto tidak cukup untuk membeli barang " + some);
                            break;                                    
                        } else {
                            jumlah_barang.set(item_code, jumlah_barang.get(item_code) + 1);
                            stock_barang.set(item_code, stock_barang.get(item_code) - 1);
                        }
                    }
                }
                
                if (isKandidat(some)) {
                    if (listKandidat.get(some - 49).getjadwal().charAt((pos % 84)) == '0') {
                        flag = false;
                        message = ("Kandidat tidak bisa di kunjungi dalam waktu ini");
                        break;
                    }
                    
                    if (max_kenalan.get(some - 49) == 0) {
                        flag = false;
                        message = ("Lama perkenalan dengan kandidat melebihi batas");
                        break;
                    } else {
                        max_kenalan.set((some - 49), max_kenalan.get(some - 49) - 1);
                    }
                    
                    energyperday -= listKandidat.get(some - 49).getenergy();
                    if (energyperday < 0) {
                        flag = false;
                        message = ("Energi Nanto tidak cukup untuk menemui kandidat");
                        break;
                    }
                    
                    pre_strenght = listKandidat.get(some - 49).getMinStrenght();
                    pre_charm    = listKandidat.get(some - 49).getMinCharm();
                    pre_brain    = listKandidat.get(some - 49).getMinBrain();
                    
                    if (val_strenght < pre_strenght) {
                        flag = false;
                        message = ("Atribut strenght tidak cukup untuk menemui kandidat");
                        break;
                    }
                    
                    if (val_charm < pre_charm) {
                        flag = false;
                        message = ("Atribut charm tidak cukup untuk menemui kandidat");
                        break;
                    }
                    
                    if (val_brain < pre_brain) {
                        flag = false;
                        message = ("Atribut brain tidak cukup untuk menemui kandidat");
                        break;
                    }
                    
                    if (!(listKandidat.get(some - 49).getprerequisite().equalsIgnoreCase("-"))) {
                        for(int i = 0; i < listKandidat.get(some - 49).getjmhpre(); i++) {
                            item_code = searchBarang(listKandidat.get(some - 49).getprerequisite().charAt(i));
                            if (jumlah_barang.get(item_code) == 0 ) { 
                                flag = false;
                                message = ("Barang tidak cukup untuk bertemu kandidat");
                                break;
                            } else {
                                jumlah_barang.set(item_code, jumlah_barang.get(item_code) - 1);
                            }
                        }
                    }
                }
                
                if(isTempat(some)) {
                    if(listBangunan.get(getBangunan(some)).getJadwal().charAt((pos % 84)) == '0') {
                        flag = false;
                        message = ("Tempat sedang tidak bisa di kunjungi dalam waktu ini");
                        break;                        
                    }

                    energyperday -= listBangunan.get(getBangunan(some)).getEnegyWasted();
                    
                    if (energyperday < 0) {
                        flag = false;
                        message = ("Energi Nanto tidak cukup untuk pergi ke " + listBangunan.get(getBangunan(some)).getTipe());
                        break;                        
                    }
                    
                    switch(some) {
                        case 'm':
                            val_money    += listBangunan.get(getBangunan(some)).getAtributAddition();
                            break;
                        case 'g':
                            val_strenght += listBangunan.get(getBangunan(some)).getAtributAddition();
                            break;
                        case 'c':
                            val_charm    += listBangunan.get(getBangunan(some)).getAtributAddition();
                            break;
                        case 'u':
                            val_brain    += listBangunan.get(getBangunan(some)).getAtributAddition();
                            break;
                        default:
                            break;
                    }
                    
                }
                
                if(isEmpty(some)) {
                    
                }
                count_hour++;
            }
            
            count_day++;
        }
        
        if (flag) {
            message = (Line.length() + "#" + message);
        } else {
            message = ((pos+1) + "#" + message);
        }
        
        return  messageParser(message, hitungenlight(Line));
    }
    
    public boolean isInAll(String Line) {
        String[] array = new String[jmhKandidat];
        for (int i = 0; i < jmhKandidat; i++) {
            array[i] = "" + (i + 1);
        }
        
        boolean flag = true;
        
        for (int i = 0; i < jmhKandidat; i++) {
            if (!(Line.contains(array[i]))) {
                flag = false;
            }
        }
        
        return flag;
    }
    
    private int searchBarang(char some) {
        int temp = 99;
        for (int i = 0; i < jmhBarang; i++) {
            if (listBarang.get(i).getkode().charAt(0) == some) {
                temp = i;
            }
        }
        return temp;   
    }
    
    private boolean isEmpty(char some) {
        return (some == '0');
    }
    
    private boolean isKandidat(char some) {
        return ((some == '1') ||(some == '2') ||(some == '3') ||(some == '4') ||(some == '5') ||(some == '6') ||(some == '7') ||(some == '8') ||(some == '9') );
    }
    
    private boolean isTempat(char some) {
        return ((some == 'm') || (some == 'u') || (some == 'c') || (some == 'g'));
    }
    
    private boolean isBarang(char some) {
        return ((!(isEmpty(some))) && (!(isKandidat(some))) && (!(isTempat(some))));
    }
    
    private String messageParser(String some, int enlightenment) {
        String[] messages = some.split("#");
        
        String message;
        
        if (messages[1].contains("valid")) {
            message = messages[1] + ". Enlightenment = " + enlightenment + ".";
        } else {
            message = "Error pada karakter ke-" + messages[0] + ". " + messages[1] + ".";
        } // */
        
        return message;
    }
    
    private int getBangunan(char some) {
        switch(some) {
            case 'm':
                return 0;
            case 'g':
                return 1;
            case 'c':
                return 2;
            case 'u':
                return 3;
            default:
                return 99;
        }
    }
    
    public void print() {
        System.out.println("Money       = " + money);
        System.out.println("Weeks       = " + weeks);
        System.out.println("Energy      = " + energy);
        System.out.println("Strength    = " + strenght);
        System.out.println("Charm       = " + charm);
        System.out.println("Brain       = " + brain);
        System.out.println();
        for (int i = 0; i < listKandidat.size(); i++ ) {
            System.out.println("Kandidat ke-" + (i+1));
            listKandidat.get(i).print();
        }
        for (int i = 0; i < listBarang.size(); i++) {
            System.out.println("Barang " + listBarang.get(i).getkode());
            listBarang.get(i).print();
        }
        for (int i = 0; i < listBangunan.size(); i++) {
            System.out.println("Bangunan " + listBangunan.get(i).getTipe());
            listBangunan.get(i).print();
        }
        System.out.println();
    }
}
